﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.IO;
using System.Xml.Serialization;
using BrowserGameFramework.Common.Logging;

namespace BrowserGameFramework.Common.XmlHelper
{
    public static class XmlHelper
    {

        /// <summary>
        /// Transform an xml with xsl. Use XslCompiledTransform
        /// </summary>
        /// <param name="xml">Xml as string</param>
        /// <param name="xsl">xsl as string</param>
        /// <param name="error">Xsl errors</param>
        /// <returns>string with transformed xml</returns>
        public static string TransformCompiled(string xml, string xsl, out string errMsg)
        {
            try
            {
                Trace.TraceEnterEvent("TransformCompiled");

                errMsg = string.Empty;
                XslCompiledTransform xslt = new XslCompiledTransform();
                StringReader docReader = new StringReader(xml);
                StringReader sheetReader = new StringReader(xsl);

                XPathDocument doc = new XPathDocument(docReader);
                XPathDocument sheet = new XPathDocument(sheetReader);

                xslt.Load(sheet);

                StringBuilder builder = new StringBuilder();
                StringWriter output = new StringWriter(builder);

                xslt.Transform(doc, new XmlTextWriter(output));

                Trace.TraceLeaveEvent("TransformCompiled");
                return builder.ToString();
            }
            catch (Exception ex)
            {
                errMsg = ex.Message;
                return string.Empty;
            }
        }

        /// <summary>
        /// Transform an xml with xsl. Use XslCompiledTransform
        /// </summary>
        /// <param name="doc">Document as Xpathdocument</param>
        /// <param name="xsl">XslSheet as Xpathdocument</param>
        /// <param name="errMsg">Errormessage</param>
        /// <returns>Transformed Xpathdocument</returns>
        public static XPathDocument TransformCompiled(XPathDocument doc, XPathDocument xsl, out string errMsg)
        {
            try
            {
                errMsg = string.Empty;
                XslCompiledTransform xslt = new XslCompiledTransform();
                StringBuilder builder = new StringBuilder();
                StringWriter writer = new StringWriter(builder);

                xslt.Load(xsl);
                xslt.Transform(doc, new XmlTextWriter(writer));

                StringReader reader = new StringReader(builder.ToString());
                XPathDocument result = new XPathDocument(reader);
                
                return result;
            }
            catch (Exception ex)
            {
                errMsg = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Gets a Object from XML with serialization
        /// </summary>
        /// <param name="doc">Source XmlDocument</param>
        /// <param name="type">Targed Type</param>
        /// <returns>Object (Cast it to your type)</returns>
        public static object GetObjectFromXml(XmlDocument doc, Type type)
        {
            XmlSerializer serializer = new XmlSerializer(type);
            StringReader reader = new StringReader(doc.InnerText);
            object result = serializer.Deserialize(reader);
            
            return result;
        }

        /// <summary>
        /// Gets a Object from XML with serialization
        /// </summary>
        /// <param name="doc">Source XmlPathDocument</param>
        /// <param name="type">Targed Type</param>
        /// <returns>Object (Cast it to your type)</returns>
        public static object GetObjectFromXml(XPathDocument xDoc, Type type)
        {
            XmlSerializer serializer = new XmlSerializer(type);
            XPathNavigator navi = xDoc.CreateNavigator();

            StringReader reader = new StringReader(navi.OuterXml);

            return serializer.Deserialize(reader);
        }

        /// <summary>
        /// Gets a xmlstring from object
        /// </summary>
        /// <param name="obj">Input object</param>
        /// <returns>Xml string</returns>
        public static string GetXmlStringFromObject(object obj)
        {
            XmlSerializer serializer = new XmlSerializer(obj.GetType());
            StringBuilder builder = new StringBuilder();
            StringWriter writer = new StringWriter(builder);
            serializer.Serialize(writer, obj);

            return builder.ToString();
        }
    }
}
